﻿using System.Collections.Generic;
using System.Web.Mvc;
using System.Linq;
using User.Global.Contracts.Message;
using User.Web.UI.Helper.Messages;

/// <summary>
/// HTML Helper Extensions für das Anzeigen der Messageboxen
/// </summary>
public static class HtmlHelperMessage
{
    #region Public Functions
    /// <summary>
    /// Prüft ob im TempData Messages hinterlegt wurden und wenn ja dann werden diese angezeigt.
    /// nach einem Request ist Tempdata auch direkt wieder leer, ist nur für einen Request aktiv!
    /// Außerdem wird überprüft ob die Modeldaten ebenfalls einen Fehler enthalten und dieser wird hier ebenfalls ausgegeben
    /// 
    /// http://stackoverflow.com/questions/4642845/asp-net-mvc-how-to-preserve-modelstate-errors-across-redirecttoaction
    /// </summary>
    /// <returns>HTML Konstrukt was eine Custom Message anzeigt.</returns>
    public static MvcHtmlString ShowCustomMessage(this HtmlHelper helper)
    {
        //Eine neue Messageliste initialisieren
        List<IMessage> messages = new List<IMessage>();

        //Prüfen ob der passende Einträge im TempData vorhanden sind, die wir dort selbst abgelegt haben
        if (helper.ViewContext.Controller.TempData[CustomMessage.TempMessageString] != null)
        {
            //den Tempdata Liste der Nachrichten abrufen
            messages = (List<IMessage>)helper.ViewContext.Controller.TempData[CustomMessage.TempMessageString];
        }

        //Nur prüfen ob Fehler im Modelstate sind, wenn dieser auch nicht valide ist.
        if (!helper.ViewData.ModelState.IsValid)
        {
            //Nach Meldungen die Vom System im Modelstatus abgelegt wurden suchen
            //Ebenfalls den aktuellen Modelstatus nach meldungen durchsuchen, dabei handelt es sich immer um Fehlermeldungen!
            foreach (var key in helper.ViewData.ModelState.Keys)
            {
                ModelState state;
                if (helper.ViewData.ModelState.TryGetValue(key, out state))
                {
                    foreach (var err in state.Errors)
                    {
                        //Bei den Meldungen im Modelstate handelt es sich immer um einen Fehler. Die Fehler dem Modelstate hinzufügen
                        messages.Add(new Message(helper.Encode(err.ErrorMessage), MessageTypes.error));
                    }
                }
            }    
        }

        string html = string.Empty;
        //Unsere Messages erstellen. Dabei wird jede Message in einer eigenen Fehlermeldung ausgegeben und sortiert ausgeben von Fehler nach OK
        foreach (Message message in messages.OrderByDescending(p => p.MessageType))
        {
            //Festlegen um welchen Fehlertyp es sich handelt
            string errorClass = GetMessageTypeCssString(message.MessageType);

            //Den HTML String zusammenbauen mit den Messages
            html += string.Format("<div class=\"{0}\"><button class=\"close\" data-dismiss=\"alert\" type=\"button\">×</button>{1}</div>", errorClass, message.Text);
        }

        //Damit der HTML String auch als HTML auf der Webseite ausgegeben werden kann, diesen noch umwandeln und den Rückgabewert des Helpers anpassen.    
        return new MvcHtmlString(html);
    }
    #endregion

    #region Private Functions
    /// <summary>
    /// Gibt den passenden CSS Code für den übergebenen Messagetype zurück
    /// </summary>
    /// <param name="message">Der MessageType für den der passende CSS Code zurück gegeben werden soll</param>
    private static string GetMessageTypeCssString(MessageTypes message)
    {
        string errorClass = string.Empty;
        switch (message)
        {
            case MessageTypes.error:
                errorClass = "alert alert-danger";
                break;
            case MessageTypes.warning:
                errorClass = "alert alert-warning";
                break;

            case MessageTypes.ok:
                errorClass = "alert alert-success";
                break;

            case MessageTypes.message:
                errorClass = "alert alert-info";
                break;
            default:
                errorClass = "alert";
                break;
        }

        return errorClass;
    }
    #endregion
}
